﻿using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using SmallJob.Model;
using SmallShop.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SmallShop.Services.Implements
{
    public class MMessageService : BaseMongoService<MMessage>, IMMessageService
    {
        public MMessageService()
            : base()
        {
        }

        protected override MongoDB.Driver.MongoCollection<MMessage> GetCollection()
        {
            return db.GetCollection<MMessage>("messages");
        }

        public List<MMessage> GetMessagesByShortID(String shortid)
        {
            var query = Query<MMessage>.EQ(m => m.ParentID, shortid);
            var lst = GetCollection().Find(query).SetSortOrder(SortBy<MMessage>.Descending(m => m.Date)).SetLimit(20).ToList();
            lst = lst.OrderBy(m => m.Date).ToList();
            return lst;
        }

        public long CountUnread(int userID)
        {
            var lsttype = new List<int>();
            lsttype.Add((int)MessageType.User_User);
            lsttype.Add((int)MessageType.PROVIDE);
            lsttype.Add((int)MessageType.REQUEST);
            var query = Query.And(
                    Query<MMessage>.EQ(m => m.ReceiverID, userID),
                    Query<MMessage>.EQ(m => m.IsRead, BsonValue.Create(false)),
                    Query<MMessage>.In(m => m.Type, lsttype)
                );
            var ctrn = GetCollection().Find(query).Count();
            return ctrn;
        }

        public long CountUnreadOrder(int userID)
        {
            var lsttype = new List<int>();
            lsttype.Add((int)MessageType.ORDER_PROVIDE);
            lsttype.Add((int)MessageType.ORDER_REQUEST);
            var query = Query.And(
                    Query<MMessage>.EQ(m => m.ReceiverID, userID),
                    Query<MMessage>.EQ(m => m.IsRead, BsonValue.Create(false)),
                    Query<MMessage>.In(m => m.Type, lsttype)
                );
            var test = GetCollection().Find(query).ToList();
            return GetCollection().Find(query).Count();
        }

        public void UpdateStatusMessage(MMessage item)
        {
            var query = Query<MMessage>.EQ(m => m.Id, item.Id);
            var update = Update<MMessage>.Set(m => m.IsRead, item.IsRead);
            GetCollection().Update(query, update);
        }

        public List<MMessage> GetMessagesByPage(int page, int pagesize, out long total, String shortid)
        {
            var query = Query<MMessage>.EQ(m => m.ParentID, shortid);
            int skip = (page - 1) * pagesize;
            var cursor = GetCollection().Find(query);
            cursor.SetSortOrder(SortBy<MMessage>.Descending(m => m.Date));
            cursor.SetSkip(skip);
            cursor.SetLimit(pagesize);
            total = cursor.Count();
            var lst = cursor.ToList();
            return lst.OrderBy(m => m.Date).ToList();
        }

        public void AllowDownload(string shortid)
        {
            var query = Query.And(
                    Query<MMessage>.EQ(m => m.ParentID, shortid),
                    Query<MMessage>.Exists(m => m.Info),
                    Query<MMessage>.EQ(m => m.Info.Type, (int)EEmbedInfoType.Delivery)
                );
            var update = Update<MMessage>.Set(m => m.Info.AllowDownload, new BsonBoolean(true));
            GetCollection().Update(query, update, UpdateFlags.Multi);
        }

        public List<MMessage> GetNewwestNotity(int userid)
        {
            var query = Query.And(
               Query<MMessage>.EQ(m => m.ReceiverID, userid),
               Query<MMessage>.EQ(m => m.IsRead, new BsonBoolean(false)),
               Query<MMessage>.EQ(m => m.Type, (int)MessageType.System_Notify)
           );
            var lst = GetCollection().Find(query).SetSortOrder(SortBy<MMessage>.Descending(m => m.Date)).ToList();
            return lst;
        }
        public long CountNewwestNotity(int userid)
        {
            var query = Query.And(
               Query<MMessage>.EQ(m => m.ReceiverID, userid),
               Query<MMessage>.EQ(m => m.IsRead, new BsonBoolean(false)),
               Query<MMessage>.EQ(m => m.Type, (int)MessageType.System_Notify)
           );
            var lst = GetCollection().Find(query).Count();
            return lst;
        }
        public List<MMessage> GetNotifyByPage(int page, int pagesize, out long total, int userid)
        {
            var query = Query.And(
               Query<MMessage>.EQ(m => m.ReceiverID, userid),
               Query<MMessage>.EQ(m => m.Type, (int)MessageType.System_Notify)
           );
            int skip = (page - 1) * pagesize;
            var cursor = GetCollection().Find(query);
            cursor.SetSortOrder(SortBy<MMessage>.Descending(m => m.Date));
            cursor.SetSkip(skip);
            cursor.SetLimit(pagesize);
            total = cursor.Count();
            var lst = cursor.ToList();
            return lst.ToList();
        }



        public long GetUnReadByUserAndRequest(int userid)
        {
            var query = Query.And(
                    Query<MMessage>.EQ(m => m.ReceiverID, userid),
                    Query<MMessage>.EQ(m => m.Type, (int)MessageType.REQUEST),
                    Query<MMessage>.EQ(m => m.IsRead, new BsonBoolean(false))
                );
            return GetCollection().Find(query).Count();
        }

        public long GetUnReadByUserAndProvide(int userid)
        {
            var query = Query.And(
                   Query<MMessage>.EQ(m => m.ReceiverID, userid),
                   Query<MMessage>.EQ(m => m.Type, (int)MessageType.PROVIDE),
                    Query<MMessage>.EQ(m => m.IsRead, new BsonBoolean(false))
               );
            return GetCollection().Find(query).Count();
        }

        public void SetReadNotify(string notifyid)
        {
            var query = Query<MMessage>.EQ(m => m.Id, new ObjectId(notifyid));
            var update = Update<MMessage>.Set(m => m.IsRead, new BsonBoolean(true));
            GetCollection().Update(query, update);
        }


        public List<MMessage> GetByPageComplaint(int page, int pagesize, out long total)
        {
            var query = Query.And(
                 Query<MMessage>.EQ(m => m.ReceiverID, (int)EUserID.SystemUser),
                 Query<MMessage>.EQ(m => m.Type, (int)MessageType.Message_Complaint)
            );
            int skip = (page - 1) * pagesize;
            var cursor = GetCollection().Find(query);
            cursor.SetSortOrder(SortBy<MMessage>.Ascending(m => m.IsRead).Descending(m => m.Date));
            cursor.SetSkip(skip);
            cursor.SetLimit(pagesize);
            total = cursor.Count();
            var lst = cursor.ToList();
            return lst.ToList();
        }

        public List<MMessage> GetByPageComplaintFilter(int page, int pagesize, out long total, string filter)
        {
            var query = Query.And(
            Query<MMessage>.EQ(m => m.ReceiverID, (int)EUserID.SystemUser),
            Query<MMessage>.EQ(m => m.Type, (int)MessageType.Message_Complaint)   
             );
            int skip = (page - 1) * pagesize;
            var cursor = GetCollection().Find(query);
            cursor.SetSortOrder(SortBy<MMessage>.Ascending(m => m.IsRead).Descending(m => m.Date));
            cursor.SetSkip(skip);
            cursor.SetLimit(pagesize);
            total = cursor.Count();
            var lst = cursor.ToList();
            return lst.ToList();
        }

        public void SetReadComplaint(string complaintid)
        {
            var query = Query<MMessage>.EQ(m => m.Id, new ObjectId(complaintid));
            var update = Update<MMessage>.Set(m => m.IsRead, new BsonBoolean(true));
            GetCollection().Update(query, update);
        }
    }
}